package com.example.sso.client.controller;

import com.example.sso.client.entity.TokenInfo;
import com.example.sso.client.entity.UserInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

@Controller
public class LoginController {

    @Value("${sso.server.url}")
    private String ssoServerUrl;
    
    @Value("${sso.client.id}")
    private String clientId;
    
    @Value("${sso.client.secret}")
    private String clientSecret;
    
    @Value("${sso.client.callback.url}")
    private String callbackUrl;
    
    @Value("${sso.client.home.url}")
    private String homeUrl;
    
    private final RestTemplate restTemplate = new RestTemplate();

    @GetMapping("/")
    public String home(HttpSession session, Model model) {
        // 检查用户是否已登录
        UserInfo userInfo = (UserInfo) session.getAttribute("userInfo");
        if (userInfo != null) {
            model.addAttribute("userInfo", userInfo);
            return "home";
        }
        return "login";
    }

    @GetMapping("/login")
    public String login(HttpServletRequest request) throws UnsupportedEncodingException {
        // 构建登录URL
        String encodedCallbackUrl = URLEncoder.encode(callbackUrl, StandardCharsets.UTF_8);
        String encodedHomeUrl = URLEncoder.encode(homeUrl, StandardCharsets.UTF_8);
        
        String loginUrl = ssoServerUrl + "/oauth/authorize?" +
                "client_id=" + clientId +
                "&response_type=code" +
                "&scope=user_info" +
                "&redirect_uri=" + encodedCallbackUrl +
                "%3FReferer%3D" + encodedHomeUrl;
        
        return "redirect:" + loginUrl;
    }

    @GetMapping("/callback")
    public String callback(
            @RequestParam("code") String code,
            @RequestParam(value = "Referer", required = false) String referer,
            HttpSession session,
            Model model) {
        
        try {
            // 使用授权码获取令牌
            TokenInfo tokenInfo = getTokenFromCode(code);
            
            // 使用令牌获取用户信息
            UserInfo userInfo = getUserInfo(tokenInfo.getAccess_token());
            
            // 将用户信息存入session
            session.setAttribute("userInfo", userInfo);
            session.setAttribute("accessToken", tokenInfo.getAccess_token());
            
            // 重定向到原始请求页面
            if (referer != null) {
                return "redirect:" + referer;
            }
            
            return "redirect:/";
        } catch (Exception e) {
            model.addAttribute("error", "登录失败: " + e.getMessage());
            return "error";
        }
    }

    @GetMapping("/logout")
    public String logout(HttpSession session) throws UnsupportedEncodingException {
        // 获取访问令牌
        String accessToken = (String) session.getAttribute("accessToken");
        
        // 清除session
        session.invalidate();
        
        // 构建退出URL
        String encodedHomeUrl = URLEncoder.encode(homeUrl, StandardCharsets.UTF_8);
        String logoutUrl = ssoServerUrl + "/ssologout?Referer=" + encodedHomeUrl;
        
        return "redirect:" + logoutUrl;
    }

    private TokenInfo getTokenFromCode(String code) {
        // 构建请求URL
        String tokenUrl = ssoServerUrl + "/oauth/token";
        
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        
        // 设置请求参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", clientId);
        params.add("client_secret", clientSecret);
        params.add("code", code);
        params.add("grant_type", "authorization_code");
        params.add("redirect_uri", callbackUrl);
        
        // 发送请求
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
        ResponseEntity<TokenInfo> response = restTemplate.exchange(
                tokenUrl, 
                HttpMethod.POST, 
                request, 
                TokenInfo.class
        );
        
        if (response.getStatusCode() == HttpStatus.OK) {
            return response.getBody();
        } else {
            throw new RuntimeException("获取令牌失败: " + response.getStatusCode());
        }
    }

    private UserInfo getUserInfo(String accessToken) {
        // 构建请求URL
        String userInfoUrl = ssoServerUrl + "/oauth/api";
        
        // 设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        
        // 设置请求参数
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("client_id", clientId);
        params.add("token", accessToken);
        params.add("method", "user_info");
        
        // 发送请求
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);
        ResponseEntity<UserInfo> response = restTemplate.exchange(
                userInfoUrl, 
                HttpMethod.POST, 
                request, 
                UserInfo.class
        );
        
        if (response.getStatusCode() == HttpStatus.OK) {
            return response.getBody();
        } else {
            throw new RuntimeException("获取用户信息失败: " + response.getStatusCode());
        }
    }
}
    